<?php

class InternalLibMiscOperators implements CliLibrary
{
	private static $operators = array(
		ExpOperator::TYPE_PREFIX => array(
			':' => array(PREC_PREFIX, 'op_value', ':p'),
			'#' => array(PREC_PREFIX, 'op_subcontext'),
		),
		ExpOperator::TYPE_LEFT => array(
			'[' => array(PREC_ARRAY, 'op_arrayref', ExpOperator::ARRAYOP),
			'.' => array(PREC_NULL, 'op_null'),
		),
		ExpOperator::TYPE_RIGHT => array(
			'=' => array(PREC_ASSIGNMENT, 'op_assign'),
			':=' => array(PREC_ASSIGNMENT, 'op_assign_value'),
			':' => array(PREC_TERNARY, 'op_bind'),
			'?' => array(PREC_TERNARY, 'op_question'),
		)
	);

	public static function addLibrary (CliMode $mode)
	{
		$mode->addOperators(__CLASS__, self::$operators);
	}

	public static function op_value (ArgContext $args)
	{
		$args->operandCount(1);
		return $args->toValue(0);
	}

	public static function op_subcontext (ArgContext $args)
	{
		$args->operandCount(1);
		$args->subContext();
		return $args->toValue(0);
	}

	public static function op_arrayref (ArgContext $args)
	{
		$args->operandCount(2);
		$args->requireType(0, 'variable');
		return $args[0]->addIndex($args->toValue(1), $args->getContext());
	}

	public static function op_null (ArgContext $args)
	{
		$args->operandCount(2);
		$args->toValue(0);
		return $args->toValue(1);
	}

	public static function op_assign (ArgContext $args)
	{
		$args->operandCount(2);
		$args->requireType(0, 'variable');
		$args[0]->set($args[1], $args->getContext());
		return $args[1];
	}

	public static function op_assign_value (ArgContext $args)
	{
		$args->operandCount(2);
		$args->requireTypes('variable', 'value');
		$value = $args->toValue(1);
		$args[0]->set($value, $args->getContext());
		return $value;
	}

	public static function op_bind (ArgContext $args)
	{
		$args->operandCount(2);
		return new ExpBind($args[0], $args[1]);
	}

	public static function op_question (ArgContext $args)
	{
		$args->operandCount(2);
		$args->requireTypes('bool', 'bind');

		return $args->toBool(0) ? $args[1]->getLeft() : $args[1]->getRight();
	}
}